//package com.ruoyi.system.interceptor;
//
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.baomidou.mybatisplus.core.metadata.IPage;
//import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import com.ruoyi.common.core.domain.model.LoginUser;
//import com.ruoyi.common.utils.SecurityUtils;
//import com.ruoyi.common.utils.ServletUtils;
//import com.ruoyi.framework.web.service.TokenService;
//import com.ruoyi.system.domain.SysDataChangeLog;
//import com.ruoyi.system.mapper.SysDataChangeLogMapper;
//import com.ruoyi.system.utils.FieldChangeUtils;
//import com.ruoyi.system.utils.SpringContextUtils;
//import org.apache.ibatis.executor.Executor;
//import org.apache.ibatis.mapping.BoundSql;
//import org.apache.ibatis.mapping.MappedStatement;
//import org.apache.ibatis.mapping.SqlCommandType;
//import org.apache.ibatis.plugin.*;
//import org.apache.ibatis.session.ResultHandler;
//import org.apache.ibatis.session.RowBounds;
//import org.springframework.stereotype.Component;
//import java.lang.reflect.Field;
//import java.util.Date;
//import java.util.List;
//import java.util.Properties;
//import java.util.concurrent.ExecutorService;
//import java.util.concurrent.Executors;
//
///**
// * MyBatis拦截器：捕获增删改操作，记录字段级变更日志
// */
//@Component
//@Intercepts({
//    @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
//    @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
//})
//public class DataChangeInterceptor2 implements Interceptor {
//
//    // 异步线程池：避免日志记录影响主流程
//    private static final ExecutorService executorService = Executors.newFixedThreadPool(5);
//
//    // Mapper和服务：延迟获取避免循环依赖
//    private SysDataChangeLogMapper changeLogMapper;
//    private TokenService tokenService;
//
//    @Override
//    public Object intercept(Invocation invocation) throws Throwable {
//        // 初始化依赖（延迟加载）
//        initDependencies();
//
//        MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
//        Object parameter = invocation.getArgs()[1];
//        SqlCommandType commandType = ms.getSqlCommandType();
//
//        // 处理增删改操作
//        if (commandType == SqlCommandType.INSERT ||
//            commandType == SqlCommandType.UPDATE ||
//            commandType == SqlCommandType.DELETE) {
//
//            // 获取表名和记录ID
//            String tableName = getTableName(parameter);
//            String recordId = getRecordId(parameter, commandType);
//
//            // 获取旧数据（更新和删除操作需要）
//            Object oldData = (commandType == SqlCommandType.UPDATE || commandType == SqlCommandType.DELETE)
//                ? getOldData(ms, parameter, recordId) : null;
//
//            // 执行原操作
//            Object result = invocation.proceed();
//
//            // 异步记录变更日志
//            executorService.submit(() -> {
//                try {
//                    recordChangeLog(commandType, tableName, recordId, oldData, parameter);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            });
//
//            return result;
//        }
//
//        // 查询操作不处理
//        return invocation.proceed();
//    }
//
//    /**
//     * 初始化依赖（通过Spring上下文获取）
//     */
//    private void initDependencies() {
//        if (changeLogMapper == null) {
//            changeLogMapper = SpringContextUtils.getBean(SysDataChangeLogMapper.class);
//        }
//        if (tokenService == null) {
//            tokenService = SpringContextUtils.getBean(TokenService.class);
//        }
//    }
//
//    /**
//     * 记录字段变更日志
//     */
//    private void recordChangeLog(SqlCommandType commandType, String tableName, String recordId,
//                                Object oldData, Object newData) {
//        // 获取当前操作用户
//        String operateBy = "system";
//        try {
//            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
//            if (loginUser != null && loginUser.getUser() != null) {
//                operateBy = loginUser.getUser().getUserName();
//            }
//        } catch (Exception e) {
//            // 非Web环境默认使用system
//        }
//
//        // 获取字段变更
//        List<FieldChangeUtils.FieldDiff> diffs = null;
//        switch (commandType) {
//            case INSERT:
//                diffs = FieldChangeUtils.getInsertFields(extractRealParameter(newData));
//                break;
//            case UPDATE:
//                diffs = FieldChangeUtils.compare(oldData, extractRealParameter(newData));
//                break;
//            case DELETE:
//                diffs = FieldChangeUtils.getDeleteFields(oldData);
//                break;
//        }
//
//        // 保存变更日志
//        if (diffs != null && !diffs.isEmpty()) {
//            for (FieldChangeUtils.FieldDiff diff : diffs) {
//                SysDataChangeLog log = new SysDataChangeLog();
//                log.setTableName(tableName);
//                log.setRecordId(recordId);
//                log.setOperateType(commandType.name().toLowerCase());
//                log.setFieldName(diff.getFieldName());
//                log.setOldValue(diff.getOldValue());
//                log.setNewValue(diff.getNewValue());
//                log.setOperateTime(new Date());
//                log.setOperateBy(operateBy);
//                changeLogMapper.insert(log);
//            }
//        }
//    }
//
//    /**
//     * 从参数中提取实际的实体对象（处理包装类）
//     */
//    private Object extractRealParameter(Object parameter) {
//        if (parameter == null) return null;
//
//        // 处理MyBatis-Plus的分页查询对象
//        if (parameter instanceof Page) {
//            IPage<?> page = (Page<?>) parameter;
//            if (page.getRecords() != null && !page.getRecords().isEmpty()) {
//                return page.getRecords().get(0);
//            }
//        }
//
//        // 处理其他可能的包装类（如Map、自定义DTO）
//        try {
//            // 尝试获取"entity"字段（MyBatis-Plus的UpdateWrapper等）
//            Field entityField = parameter.getClass().getDeclaredField("entity");
//            entityField.setAccessible(true);
//            Object entity = entityField.get(parameter);
//            if (entity != null) return entity;
//        } catch (Exception e) {
//            // 忽略异常
//        }
//
//        return parameter;
//    }
//
//    /**
//     * 获取表名（基于MyBatis-Plus的@TableName注解）
//     */
//    private String getTableName(Object parameter) {
//        try {
//            Object realParam = extractRealParameter(parameter);
//            if (realParam == null) return "unknown_table";
//
//            Class<?> entityClass = realParam.getClass();
//            com.baomidou.mybatisplus.annotation.TableName tableAnn =
//                entityClass.getAnnotation(com.baomidou.mybatisplus.annotation.TableName.class);
//
//            return tableAnn != null ? tableAnn.value() : entityClass.getSimpleName();
//        } catch (Exception e) {
//            return "unknown_table";
//        }
//    }
//
//    /**
//     * 获取记录ID（主键值）
//     */
//    private String getRecordId(Object parameter, SqlCommandType commandType) {
//        try {
//            Object realParam = extractRealParameter(parameter);
//            if (realParam == null) return "unknown_id";
//
//            // 尝试获取主键字段（默认"id"，可扩展支持@TableId注解）
//            Field idField = getPrimaryKeyField(realParam.getClass());
//            if (idField != null) {
//                idField.setAccessible(true);
//                Object idValue = idField.get(realParam);
//                return idValue != null ? idValue.toString() : "unknown_id";
//            }
//        } catch (Exception e) {
//            // 忽略异常
//        }
//        return "unknown_id";
//    }
//
//    /**
//     * 获取主键字段（支持@TableId注解）
//     */
//    private Field getPrimaryKeyField(Class<?> clazz) {
//        // 先查找@TableId注解的字段
//        for (Field field : clazz.getDeclaredFields()) {
//            if (field.isAnnotationPresent(com.baomidou.mybatisplus.annotation.TableId.class)) {
//                return field;
//            }
//        }
//        // 找不到则默认查找"id"字段
//        try {
//            return clazz.getDeclaredField("id");
//        } catch (NoSuchFieldException e) {
//            return null;
//        }
//    }
//
//    /**
//     * 获取更新/删除前的旧数据
//     */
//    private Object getOldData(MappedStatement ms, Object parameter, String recordId) {
//        try {
//            // 获取实体类类型
//            Object realParam = extractRealParameter(parameter);
//            if (realParam == null) return null;
//            Class<?> entityClass = realParam.getClass();
//
//            // 获取对应的Mapper接口（需自定义Mapper注册器，这里简化实现）
//            // 实际项目中需通过实体类找到对应的Mapper并调用selectById方法
//            return null; // 简化实现，实际需完善
//        } catch (Exception e) {
//            return null;
//        }
//    }
//
//    @Override
//    public Object plugin(Object target) {
//        return Plugin.wrap(target, this);
//    }
//
//    @Override
//    public void setProperties(Properties properties) {}
//}
